import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Vector;

import javax.swing.JOptionPane;


public class roomManager {
	
	// room data controls
	/**
	 * 0 <= king room
	 * 1 <= large room
	 * 2 <= medium room
	 * 3 <= small room
	 * 4 <= rest room
	 */
	private int[] roomType;
	/**
	 * the rightmost digit is 0 <= empty
	 * the rightmost digit is 1 <= occupied
	 * the rightmost digit is 2 <= in the cleaning
	 * the rightmost digit is 3 <= need to clean
	 * the rest digits mean the times of reservation
	 */
	private int[] roomState;
	private roomInfo[] rooms;
	private roomRect[] roomRects;
	
	// current host data controls
	private Vector<host> hosts;
	
	public roomManager(){
		initData();
	}
	
	public void initData(){
		// initialize roomType
		roomType = new int[17];
		roomType[0] = 1;
		roomType[1] = 1;
		roomType[2] = 2;
		roomType[3] = 2;
		roomType[4] = 1;
		roomType[5] = 2;
		roomType[6] = 2;
		roomType[7] = 2;
		roomType[8] = 2;
		roomType[9] = 3;
		roomType[10] = 3;
		roomType[11] = 3;
		roomType[12] = 0;
		roomType[13] = 3;
		roomType[14] = 2;
		roomType[15] = 1;
		roomType[16] = 4;
		
		// initialize hosts
		hosts = new Vector<host>();
		// initialize room state
		roomState = new int[17];
		for (int i=0; i<roomState.length; i++)
			roomState[i] = 0;
		// initialize room info
		rooms = new roomInfo[17];
		for (int i=0; i<rooms.length; i++)
			rooms[i] = new roomInfo(i+1);
		
		roomRects = new roomRect[17];
		roomRects[0] = new roomRect(1, 1, 10, 10);
		roomRects[1] = new roomRect(2, 1, 220, 10);
		roomRects[2] = new roomRect(3, 2, 430, 10);
		roomRects[3] = new roomRect(4, 2, 430, 140);
		roomRects[4] = new roomRect(5, 1, 640, 10);
		roomRects[5] = new roomRect(6, 2, 640, 242);
		roomRects[6] = new roomRect(7, 2, 430, 270);
		roomRects[7] = new roomRect(8, 2, 220, 220);
		roomRects[8] = new roomRect(9, 2, 10, 220);
		roomRects[9] = new roomRect(10, 3, 10, 360);
		roomRects[10] = new roomRect(11, 3, 120, 360);
		roomRects[11] = new roomRect(12, 3, 320, 360);
		roomRects[12] = new roomRect(13, 0, 430, 400);
		roomRects[13] = new roomRect(14, 3, 320, 440);
		roomRects[14] = new roomRect(15, 2, 220, 525);
		roomRects[15] = new roomRect(16, 1, 10, 450);
		roomRects[16] = new roomRect(17, 4, 230, 360);
		for (int i=0; i<roomRects.length; i++)
			roomRects[i].setRoomInfo(rooms[i]);
	}
	
	public roomRect[] getRoomRects(){
		return roomRects;
	}
	public int[] getRoomState(){
		return roomState;
	}
	
	// get rooms of selected type and state
	public Vector<String> getAvailableRooms(String s, int state){
		Vector<String> list = new Vector<String>();
		int type = -1;
		if (s.equals("less than 5"))
			type = 3;
		else if (s.equals("between 5 and 10"))
			type = 2;
		else if (s.equals("between 10 and 20"))
			type = 1;
		else if (s.equals("more than 20"))
			type = 0;
		list.add("");
		for (int i=0; i<roomType.length-1; i++){
			if (roomType[i] <= type && roomState[i] == state)
				list.add(""+rooms[i].getRoomNum());
			if (roomType[i] <= type && state == -1)
				list.add(""+rooms[i].getRoomNum()); 
		}
		return list;
	}
	
	// find the room of the selected name
	public roomInfo searchRoom(int num){
		return rooms[num-1];
	}
	
	// get the type of the selected room
	public String typeOfSelectedRoom(int roomNum){
		String s = "";
		int type = roomType[roomNum-1];
		if (type == 3)
			s = "less than 5";
		else if (type == 2)
			s = "between 5 and 10";
		else if (type == 1)
			s = "between 10 and 20"; 
		else if (type == 0)
			s = "more than 20"; 
		return s;
	}
	
	// get room information
	public String toString(roomInfo room){
		String s = "Room Number: "+ room.getRoomNum()+"\n";
		
		if (roomType[room.getRoomNum()-1] == 0)
			s+="Room Type: \t"+"King";
		else if (roomType[room.getRoomNum()-1] == 1)
			s+="Room Type: \t"+"Large";
		else if (roomType[room.getRoomNum()-1] == 2)
			s+="Room Type: \t"+"Medium";
		else if (roomType[room.getRoomNum()-1] == 3)
			s+="Room Type: \t"+"Small";
		s+="\n";
		if (roomState[room.getRoomNum()-1] == 0)
			s+="Room State: \t"+"Empty";
		else if (roomState[room.getRoomNum()-1] == 1)
			s+="Room State: \t"+"Occupied";
		else if (roomState[room.getRoomNum()-1] == 2)
			s+="Room State: \t"+"In the Cleaning";
		else if (roomState[room.getRoomNum()-1] == 3)
			s+="Room State: \t"+"Need to Clean";
		s+="\n";
		s+=room.toString();
		return s;
	}
	
	// return room schedule
	public String reservationString(int room){
		roomInfo temp = rooms[room-1];
		Vector<host> tmp = temp.getHosts();
		if (!temp.getCurrent().getName().equals(""))
			tmp.add(0, temp.getCurrent());
		String s = "Occupied Infomation \n";
		DateFormat format = new SimpleDateFormat("yyyy/MM/dd hh:mm");
		for (int i=0; i<tmp.size(); i++)
			s += "Start from "+format.format(tmp.get(i).getStartTime().getTime()) + " to "+format.format(tmp.get(i).getEndTime().getTime())+"\n";
		return s;
	}
	
	// find rooms in the selected type
	/**
	public String[] findRoomType(int type){
		Vector<String> list = new Vector<String>();
		for (int i=0; i<roomState.length; i++)
			if (roomState[i] == type)
				list.add(i+"");
		if (list.isEmpty())
			return null;
		String[] roomList = new String[list.size()];
		for (int i=0; i<list.size(); i++)
			roomList[i] = list.get(i);
		return roomList;
	}
	*/
	
	// update room state
	public void updateRoomState(int roomName, int type){
		roomState[roomName-1] = type;
	}
	
	// find rooms in the selected state
	public Vector<String> findRoomState(int type){
		Vector<String> list = new Vector<String>();
		list.add("");
		for (int i=0; i<roomState.length; i++)
			if (roomState[i] == type)
				list.add(""+(i+1));
		return list;
	}
	
	// add reservation
	public boolean addReservation(host initHost, int initRoomNum){
		if (rooms[initRoomNum-1].addReservation(initHost)){
			roomState[initRoomNum-1] += 10;
			return true;
		}
		else return false;
	}
	
	// delete reservation
	public boolean deleteReservation(String initHost, String initTime, int initRoomNum){
		if (rooms[initRoomNum-1].deleteReservation(initHost, initTime)){
			roomState[initRoomNum-1] -= 10;
			return true;
		}
		else return false;
		
	}
	
	// get reservation list
	public Vector<String> reservationRooms(){
		Vector<String> r = new Vector<String>();
		r.add("");
		for (int i=0; i<roomState.length; i++)
			if (roomState[i] >= 10)
				r.add(""+(i+1));
		return r;
	}
	
	// get the type of the larger room 
	public roomInfo compareType(int room1, int room2){
		roomInfo type = rooms[room1-1];
		if ( roomType[room1-1] >  roomType[room2-1])
			type =  rooms[room2-1];
		return type;
		
	}
	
	// we get the larger room info and merge to the destination room
	public void mergeRoom(int room1, int room2, int destination){
		// merge two rooms to the destination room
		roomInfo larger = compareType(room1, room2);	
		
		// merge two host to the destination host
		host newHost = larger.getCurrent();
		if (larger.getRoomNum() == room1)
			newHost.addRecords(rooms[room2-1].getCurrent().getRecords());
		else newHost.addRecords(rooms[room1-1].getCurrent().getRecords());
		newHost.setRoomNum(destination);
		newHost.setAmount(typeOfSelectedRoom(destination));
		rooms[destination-1].setCurrentHost(newHost);
		roomRects[destination-1].setRoomInfo(rooms[destination-1]);
		
		System.out.println(rooms[destination-1].getCurrent().toString());
		
		// update new host and room
		hosts.remove(rooms[room1-1].getCurrent());
		hosts.remove(rooms[room2-1].getCurrent());
		rooms[room1-1].initialize();
		rooms[room2-1].initialize();
		roomRects[room1-1].setRoomInfo(rooms[room1-1]);
		roomRects[room2-1].setRoomInfo(rooms[room2-1]);
		roomState[room1-1] = 3;
		roomState[room2-1] = 3;
		roomState[destination-1] = 1;
		hosts.add(newHost);
	}
	
	// change from room1 to room2
	public void changeRooms(int room1, int room2){
		host temp = rooms[room1-1].getCurrent();
		temp.setAmount(typeOfSelectedRoom(room2));
		temp.addRecords("Change from Room "+ room1 + " to Room "+ room2);
		temp.setRoomNum(room2);
		rooms[room2-1].setCurrentHost(temp);
		rooms[room1-1].initialize();
		roomState[room2-1] = 1;
		roomState[room1-1] = 3;
	}
	
	// add host
	public void addCurrentHost(host newHost){
		hosts.add(newHost);
		rooms[newHost.getRoomNum()-1].setCurrentHost(newHost);
	}
	
	// add record to the selected host
	public void updateHostRecords(host initHost, String s){
		int index = hosts.indexOf(initHost);
		hosts.get(index).addRecords(s);
	}
	
	// get host by selected name
	public host getHostByName(String initName){
		String name = "";
		for (int i=0; i<hosts.size(); i++){
			name = hosts.get(i).getName();
			if (name.equals(initName))
				return hosts.get(i);
		}
		return null;
	}
	
	// get the hosts in the waiting list of the selected room
	public Vector<host> getReservations(int roomNum){
		return rooms[roomNum-1].getHosts();
	}
	
	public host getCurrentHost(int roomNum){
		return rooms[roomNum-1].getCurrent();
	}
	
	// delete host 
	public void deleteHost(host h){
		hosts.remove(h);
	}
	
	// check whether the time is in the occupied period
	public boolean in(Calendar c){
		for (int i=0; i<rooms.length; i++)
			if (rooms[i].in(c))
				return true;
		return false;
	}
	
	public boolean signin(host h){
		Calendar c = Calendar.getInstance();
		if (c.compareTo(h.getStartTime())>=0 && c.compareTo(h.getEndTime())<0){
			roomRects[h.getRoomNum()-1].getRoomInfo().setCurrentHost(h);
			roomRects[h.getRoomNum()-1].getRoomInfo().getHosts().remove(h);
			return true;
		}
		else return false;
	}
}
